package com.jfinal.weixin.mvc.jfinal;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.utils.Xml2StringKit;
import com.jfinal.weixin.kit.MsgEncryptKit;
import com.jfinal.weixin.msg.WeixinConfig;
import com.jfinal.weixin.mvc.WeChatKit;
import lombok.extern.slf4j.Slf4j;

/**
 * 接收微信服务器消息，自动解析成 InMsg 并分发到相应的处理方法
 */
@Slf4j
public abstract class BasicWeChatMessageController extends Controller {

    public abstract WeixinConfig getWeChatConfig(String id);     //继承实现配置微信帐号信息

    /**
     * weixin 公众号服务器调用唯一入口，即在开发者中心输入的 URL 必须要指向此 action
     * 多帐号支持,通过在TokenURL后设置一个帐号ID(可以是appid,也可以是自定义的Id)
     * 消息进入时通过继承实现getWeChatConfig(id)得到帐号信息,也可自己重新扩展实现BasicWeChatMessageController
     * TokenURL: /message/id
     */
    @Before(WeChatInterceptor.class)
    public void message() {

        String appId = getPara();     //从URL之中获取appId

        String inMsgXml = "";
        String outMsgXml = "";
        try {
            /**
             * 取得继承的微信帐号对象
             */
            WeixinConfig wechatConfig = getWeChatConfig(appId);
            // 解析消息并根据消息类型分发到相应的处理方法
            if (wechatConfig != null) {
                inMsgXml = Xml2StringKit.parseXmlStr(getRequest());

                // 开发模式输出微信服务发送过来的  xml 消息
                if (wechatConfig.isDevMode()) {
                    System.out.println("接收消息:");
                    System.out.println(inMsgXml);
                    System.out.println("--------------------------------------------------------------------------------\n");
                }

                //判断消息是否加密，处理消息加密模式
                String signature = getRequest().getParameter("msg_signature");
                String timestamp = getRequest().getParameter("timestamp");
                String nonce = getRequest().getParameter("nonce");
                String encrypt_type = getRequest().getParameter("encrypt_type");
                boolean isEncode = false;
                if (StrKit.notBlank(encrypt_type) && encrypt_type.equals("aes")) {
                    isEncode = true;
                }

                if (isEncode) {
                    inMsgXml = MsgEncryptKit.decrypt(wechatConfig, inMsgXml, timestamp, nonce, signature);
                }

                // 开发模式输出微信服务发送过来的  xml 消息
                if (wechatConfig.isDevMode()) {
                    System.out.println("解密消息:");
                    System.out.println(inMsgXml);
                    System.out.println("--------------------------------------------------------------------------------\n");
                }

                /**
                 * 处理消息返回
                 */
                outMsgXml = WeChatKit.processing(inMsgXml, wechatConfig);

                // 开发模式输出返回微信服务的xml 消息
                if (wechatConfig.isDevMode()) {
                    System.out.println("返回消息:");
                    System.out.println(outMsgXml);
                    System.out.println("--------------------------------------------------------------------------------\n");
                }

                if (isEncode) {
                    outMsgXml = MsgEncryptKit.encrypt(wechatConfig, outMsgXml, timestamp, nonce);
                }
            }
        } catch (Exception e) {
            /**
             * TODO 考虑在此构建异常返回消息实现
             */
            outMsgXml = "";    //异常时返回空并记录日志
            log.error("处理消息[{}]异常:{}", inMsgXml, e);
        } finally {
            // 开发模式向控制台输出即将发送的 OutMsg 消息的 xml 内容
            if (getWeChatConfig(appId).isDevMode()) {
                System.out.println("发送消息:");
                System.out.println(outMsgXml);
                System.out.println("--------------------------------------------------------------------------------\n");
            }
            renderText(outMsgXml, "text/xml");
        }
    }
}













